<script lang="ts" setup>
import { onMounted, ref, useTemplateRef } from 'vue';
import { useRoute } from 'vue-router';
import { EMediaQueryUtil } from 'exploria-ui';
import { gsap } from 'gsap';
import { ScrollTrigger } from 'gsap/ScrollTrigger';
import { useSystemStore } from '@/stores/systemStore.ts';

gsap.registerPlugin(ScrollTrigger);

const route = useRoute();
const section = ref<string[]>([]);
const systemStore = useSystemStore();
let timeline: gsap.core.Timeline | null = null;
const handlePercentage = () => {
    if (timeline) {
        timeline.kill();
    }
    const pageLayoutLeft = pageLayoutRef.value!.querySelector(
        '.page-layout-left',
    ) as HTMLElement;
    timeline = gsap.timeline({
        scrollTrigger: {
            scroller: pageLayoutLeft, // 指定滚动容器
            trigger: pageLayoutLeft,
            start: `-${pageLayoutLeft.scrollTop} top`,
            end: `${pageLayoutLeft.scrollHeight - pageLayoutLeft.scrollTop} bottom`,
            scrub: true,
            invalidateOnRefresh: true,
            // TODO 待解决 start/end 标记位置不精确问题
            // markers: true,
            onUpdate: (self) => (systemStore.percentage = self.progress * 100),
        },
    });
};

onMounted(() => {
    if (route.hash) {
        const element = pageLayoutRef.value!.querySelector(
            `.demo-box.${route.hash.substring(1)}`,
        );
        element &&
            element.scrollIntoView({ behavior: 'instant', block: 'center' });
    }

    const pageLayoutLeft = pageLayoutRef.value!.querySelector(
        '.page-layout-left',
    ) as HTMLElement;

    pageLayoutLeft.querySelectorAll('.demo-box').forEach((element) => {
        section.value.push(element.classList[1]!);
    });
});

const pageLayoutRef = useTemplateRef<HTMLElement>('page-layout');

const onClickOption = (option: string) => {
    const center = pageLayoutRef.value!.querySelector(
        '.page-layout-left',
    ) as HTMLElement;

    if (center.scrollHeight <= center.clientHeight) {
        // 没有滚动条
        window.location.hash = option;
        return;
    }

    const element = pageLayoutRef.value!.querySelector(
        `.page-layout-left>.demo-box.${option}`,
    );
    element && element.scrollIntoView({ behavior: 'smooth', block: 'center' });
    // window.location.hash 由 onScroll 触发设置
};

const onScroll = (e: Event) => {
    const titleList = (e.currentTarget as HTMLElement).querySelectorAll(
        '.demo-box>.title',
    );
    const range = [0, 300] as [number, number];
    for (const title of Array.from(titleList)) {
        const rect = title.getBoundingClientRect();
        if (rect.top >= range[0] && rect.top <= range[1]) {
            window.location.hash = title.textContent as string;
        }
    }
};
</script>
<template>
    <div class="page-layout" ref="page-layout" v-size-ob="handlePercentage">
        <div class="page-layout-left" @scroll="onScroll">
            <slot />
        </div>
        <div class="page-layout-right" v-if="!EMediaQueryUtil.is('phone')">
            <div
                class="option"
                v-for="option of section"
                :key="option"
                @click="onClickOption(option)"
                :class="{ active: route.hash.substring(1) === option }"
            >
                {{ option }}
            </div>
        </div>
    </div>
</template>

<style scoped lang="scss">
@use '@/style/global.scss' as global;

.page-layout {
    overflow: hidden;
    display: flex;
    height: 100%;
    flex-direction: row;

    .page-layout-left {
        flex: 1;
        overflow-y: auto;
        scroll-behavior: smooth;

        &::-webkit-scrollbar {
            @include global.useTheme(
                phone,
                (
                    width: 0,
                )
            );

            @include global.useTheme(
                light,
                (
                    width: 0,
                )
            );

            @include global.useTheme(
                dark,
                (
                    width: 0,
                )
            );

            @include global.useTheme(
                plain,
                (
                    width: 7px,
                )
            );
        }

        &::-webkit-scrollbar-thumb {
            @include global.useTheme(
                plain,
                (
                    background-color: #ededed,
                )
            );
        }
    }

    .page-layout-right {
        overflow: auto;
        scrollbar-width: none;
        width: global.$document-aside-width;
        box-shadow: global.$box-shadow;
        border: global.$border;

        margin: calc(#{global.$header-height} + #{global.$gap} * 2) global.$gap
            global.$gap;
        background-color: global.$background-color;
        border-radius: global.$border-radius;
        backdrop-filter: global.$backdrop-filter;

        @include global.useTheme(
            plain,
            (
                margin: 0,
                backdrop-filter: none,
                border-radius: 0,
                box-shadow: none,
                border: none,
            )
        );
        @include global.useTheme(
            phone,
            (
                margin: 0,
                backdrop-filter: none,
                border-radius: 0,
                box-shadow: none,
                border: none,
            )
        );

        .option {
            color: #666;
            padding: 5px;
            margin: 10px;
            font-size: 14px;
            transition: background-color 0.1s;
            cursor: pointer;
            border-radius: global.$border-radius;

            &:hover {
                background-color: rgba(153, 190, 246, 0.47);
            }

            &.active {
                color: #ffffff;
                background-color: #99bef6;
            }
        }
    }
}
</style>
